using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
using NLog;

namespace LDNS.UI
{
    /// <summary>
    /// 主窗口类
    /// 作者: huobing
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {
        #region 属性定义

        private bool _isIpcConnected = false;
        /// <summary>
        /// IPC连接状态
        /// </summary>
        public bool IsIpcConnected
        {
            get => _isIpcConnected;
            set
            {
                _isIpcConnected = value;
                OnPropertyChanged(nameof(IsIpcConnected));
            }
        }

        private bool _isServiceRunning = false;
        /// <summary>
        /// 服务运行状态
        /// </summary>
        public bool IsServiceRunning
        {
            get => _isServiceRunning;
            set
            {
                _isServiceRunning = value;
                OnPropertyChanged(nameof(IsServiceRunning));
                OnPropertyChanged(nameof(ServiceButtonText));
            }
        }

        private int _listeningPort = 53;
        /// <summary>
        /// 监听端口
        /// </summary>
        public int ListeningPort
        {
            get => _listeningPort;
            set
            {
                _listeningPort = value;
                OnPropertyChanged(nameof(ListeningPort));
            }
        }

        private string _serviceButtonText = "启动服务";
        /// <summary>
        /// 服务按钮文本
        /// </summary>
        public string ServiceButtonText
        {
            get => _serviceButtonText;
            set
            {
                _serviceButtonText = value;
                OnPropertyChanged(nameof(ServiceButtonText));
            }
        }

        private DateTime? _serviceStartTime = null;
        /// <summary>
        /// 服务启动时间
        /// </summary>
        public DateTime? ServiceStartTime
        {
            get => _serviceStartTime;
            set
            {
                _serviceStartTime = value;
                OnPropertyChanged(nameof(ServiceStartTime));
                UpdateUptimeDisplay();
            }
        }

        private string _uptimeDisplay = "00:00:00";
        /// <summary>
        /// 运行时间显示
        /// </summary>
        public string UptimeDisplay
        {
            get => _uptimeDisplay;
            set
            {
                _uptimeDisplay = value;
                OnPropertyChanged(nameof(UptimeDisplay));
            }
        }

        private int _totalQueries = 0;
        /// <summary>
        /// 查询总数
        /// </summary>
        public int TotalQueries
        {
            get => _totalQueries;
            set
            {
                _totalQueries = value;
                OnPropertyChanged(nameof(TotalQueries));
            }
        }

        private int _cacheHits = 0;
        /// <summary>
        /// 缓存命中数
        /// </summary>
        public int CacheHits
        {
            get => _cacheHits;
            set
            {
                _cacheHits = value;
                OnPropertyChanged(nameof(CacheHits));
            }
        }

        private readonly string _version = "1.0.0";
        /// <summary>
        /// 应用版本号
        /// </summary>
        public string Version => _version;

        #endregion

        #region 字段定义
        private readonly Logger _logger = LogManager.GetCurrentClassLogger();
        private NamedPipeClientStream? _namedPipeClient;
        private CancellationTokenSource? _cts;
        private DispatcherTimer? _uptimeTimer;
        private const string PipeName = "LDNSPipe";
        private const int ReconnectDelayMilliseconds = 60000; // 1分钟重连延迟

        #endregion

        #region 事件实现

        public event PropertyChangedEventHandler? PropertyChanged;

        /// <summary>
        /// 属性变更通知
        /// </summary>
        /// <param name="propertyName">属性名</param>
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        #region 构造函数和初始化

        /// <summary>
        /// 主窗口构造函数
        /// </summary>
        public MainWindow()
        {
            try
            {
                // 直接使用当前程序集的版本号
                // 由于LDNS.UI.csproj已经引用了LDNS的版本号，这里获取的就是LDNS的版本号
                _version = Assembly.GetExecutingAssembly().GetName().Version?.ToString(3) ?? "1.0.16";
                
                _logger.Debug("MainWindow构造函数开始初始化");
                InitializeComponent();
                _logger.Debug("InitializeComponent完成");
                
                DataContext = this;
                _logger.Debug("DataContext设置完成");

                // 初始化定时器用于更新运行时间
                InitializeUptimeTimer();
                _logger.Debug("UptimeTimer初始化完成");

                // 确保窗口可见
                this.Visibility = Visibility.Visible;
                this.WindowState = WindowState.Normal;
                this.Activate();
                _logger.Debug("窗口可见性设置完成");

                // 暂时不连接IPC服务，先确保UI能够显示
                ConnectToIpcService();
                _logger.Debug("MainWindow构造函数初始化完成");
            }
            catch (Exception ex)
            {
                _logger.Debug($"MainWindow构造函数异常: {ex.Message}");
                _logger.Debug(ex.StackTrace ?? ""); // 添加null检查
                // 尝试显示错误消息
                MessageBox.Show($"初始化错误: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// 初始化运行时间定时器
        /// </summary>
        private void InitializeUptimeTimer()
        {
            _uptimeTimer = new DispatcherTimer
            {
                Interval = TimeSpan.FromSeconds(1)
            };
            _uptimeTimer.Tick += UptimeTimer_Tick;
            _uptimeTimer.IsEnabled = false;
        }

        #endregion

        #region IPC连接管理

        /// <summary>
        /// 连接到IPC服务
        /// </summary>
        private void ConnectToIpcService()
        {
            _cts = new CancellationTokenSource();
            _ = Task.Run(() => ConnectAndMonitorIpcAsync(_cts.Token));
        }

        /// <summary>
        /// 连接并监控IPC服务
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        private async Task ConnectAndMonitorIpcAsync(CancellationToken cancellationToken)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                try
                {
                    // 创建新的命名管道客户端
                    _namedPipeClient = new NamedPipeClientStream(".", PipeName, PipeDirection.InOut, PipeOptions.Asynchronous);

                    // 尝试连接
                    await _namedPipeClient.ConnectAsync(5000, cancellationToken);

                    // 连接成功
                    Dispatcher.Invoke(() =>
                    {
                        IsIpcConnected = true;
                        IsServiceRunning = true;
                    });

                    // 读取服务端发送的连接确认消息
                    var reader = new StreamReader(_namedPipeClient, Encoding.UTF8);
                    string? connectResponse = await reader.ReadLineAsync();
                    _logger.Debug($"收到连接确认: {connectResponse ?? "null"}");

                    // 查询服务启动时间和统计数据
                    await QueryServiceInformationAsync();

                    // 启用运行时间定时器
                    Dispatcher.Invoke(() =>
                    {
                        if (_uptimeTimer != null)
                        {
                            _uptimeTimer.IsEnabled = true;
                        }
                    });

                    // 监控连接状态
                    await MonitorConnectionAsync(cancellationToken);
                }
                catch (Exception ex)
                {
                    _logger.Debug($"IPC连接失败: {ex.Message}");
                    
                    // 连接失败，重置状态
                    ResetConnectionState();
                }

                // 等待重连延迟
                if (!cancellationToken.IsCancellationRequested)
                {
                    await Task.Delay(ReconnectDelayMilliseconds, cancellationToken);
                }
            }
        }

        /// <summary>
        /// 监控连接状态
        /// </summary>
        /// <param name="cancellationToken">取消令牌</param>
        private async Task MonitorConnectionAsync(CancellationToken cancellationToken)
        {
            try
            {
                // 创建一个缓冲区用于读取数据
                byte[] buffer = new byte[1024];
                
                while (_namedPipeClient != null && _namedPipeClient.IsConnected && !cancellationToken.IsCancellationRequested)
                {
                    // 异步读取数据，保持连接活跃
                    int bytesRead = await _namedPipeClient.ReadAsync(buffer, 0, buffer.Length, cancellationToken);
                    
                    if (bytesRead == 0)
                    {
                        // 连接被关闭
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.Debug($"监控连接异常: {ex.Message}");
            }
            finally
            {
                // 连接断开，重置状态
                ResetConnectionState();
            }
        }

        /// <summary>
        /// 查询服务信息
        /// </summary>
        private async Task QueryServiceInformationAsync()
        {            
            if (_namedPipeClient == null || !_namedPipeClient.IsConnected)
            {
                return;
            }

            try
            {
                // 发送查询请求
                string request = "STATUS\n";
                byte[] requestBytes = Encoding.UTF8.GetBytes(request);
                await _namedPipeClient.WriteAsync(requestBytes, 0, requestBytes.Length);
                await _namedPipeClient.FlushAsync();

                // 读取响应
                byte[] buffer = new byte[4096];
                int bytesRead = await _namedPipeClient.ReadAsync(buffer, 0, buffer.Length);
                string response = Encoding.UTF8.GetString(buffer, 0, bytesRead);

                // 解析响应数据
                ParseServiceInformation(response);
            }
            catch (Exception ex)
            {
                _logger.Debug($"查询服务信息失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 解析服务信息
        /// 作者：huobing
        /// </summary>
        /// <param name="response">响应数据</param>
        private void ParseServiceInformation(string response)
        {            
            try
            {
                // 解析响应中的服务启动时间和统计数据F
                string[] lines = response.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
                
                foreach (string line in lines)
                {
                    // 移除可能的OK: 前缀
                    string cleanLine = line.StartsWith("OK: ") ? line.Substring(4) : line;
                    
                    // 解析服务状态
                    if (cleanLine.StartsWith("服务状态: ") || cleanLine.Contains("运行状态: "))
                    {
                        string status = cleanLine.Contains("运行状态: ") ? 
                            cleanLine.Substring(cleanLine.IndexOf("运行状态: ") + 6).Trim() : 
                            cleanLine.Substring(6).Trim();
                        Dispatcher.Invoke(() =>
                        {
                            IsServiceRunning = status == "运行中";
                        });
                    }
                    // 解析监听端口
                    else if (cleanLine.StartsWith("监听端口: "))
                    {
                        string portStr = cleanLine.Substring(6).Trim();
                        if (int.TryParse(portStr, out int port))
                        {
                            Dispatcher.Invoke(() =>
                            {
                                ListeningPort = port;
                            });
                        }
                    }
                    // 解析启动时间
                    else if (cleanLine.StartsWith("启动时间: "))
                    {
                        string startTimeStr = cleanLine.Substring(6).Trim();
                        if (DateTime.TryParse(startTimeStr, out DateTime startTime) && startTimeStr != "N/A")
                        {
                            Dispatcher.Invoke(() =>
                            {
                                ServiceStartTime = startTime;
                            });
                        }
                    }
                    // 解析缓存记录数 (如果服务端有返回)
                    else if (cleanLine.StartsWith("缓存记录数: "))
                    {
                        string cacheRecordsStr = cleanLine.Substring(7).Trim();
                        if (int.TryParse(cacheRecordsStr, out int cacheRecords))
                        {
                            Dispatcher.Invoke(() =>
                            {
                                CacheHits = cacheRecords; // 使用CacheHits字段来显示缓存记录数
                            });
                        }
                    }
                    // 解析运行时间
                    else if (cleanLine.StartsWith("运行时间: "))
                    {
                        string uptimeStr = cleanLine.Substring(6).Trim();
                        Dispatcher.Invoke(() =>
                        {
                            UptimeDisplay = uptimeStr;
                            // 尝试解析运行时间来计算启动时间
                            try
                            {
                                // 提取天、小时、分钟、秒
                                int days = 0, hours = 0, minutes = 0, seconds = 0;
                                
                                if (uptimeStr.Contains("天"))
                                {
                                    int daysIndex = uptimeStr.IndexOf("天");
                                    days = int.Parse(uptimeStr.Substring(0, daysIndex).Trim());
                                }
                                
                                if (uptimeStr.Contains("小时"))
                                {
                                    int hoursIndex = uptimeStr.IndexOf("小时");
                                    int startIndex = uptimeStr.LastIndexOf(' ', hoursIndex) + 1;
                                    hours = int.Parse(uptimeStr.Substring(startIndex, hoursIndex - startIndex).Trim());
                                }
                                
                                if (uptimeStr.Contains("分钟"))
                                {
                                    int minutesIndex = uptimeStr.IndexOf("分钟");
                                    int startIndex = uptimeStr.LastIndexOf(' ', minutesIndex) + 1;
                                    minutes = int.Parse(uptimeStr.Substring(startIndex, minutesIndex - startIndex).Trim());
                                }
                                
                                if (uptimeStr.Contains("秒"))
                                {
                                    int secondsIndex = uptimeStr.IndexOf("秒");
                                    int startIndex = uptimeStr.LastIndexOf(' ', secondsIndex) + 1;
                                    seconds = int.Parse(uptimeStr.Substring(startIndex, secondsIndex - startIndex).Trim());
                                }
                                
                                // 计算启动时间
                                ServiceStartTime = DateTime.Now.AddDays(-days).AddHours(-hours).AddMinutes(-minutes).AddSeconds(-seconds);
                            }
                            catch { }
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.Debug($"解析服务信息失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 重置连接状态
        /// </summary>
        private void ResetConnectionState()
        {            
            Dispatcher.Invoke(() =>
            {
                IsIpcConnected = false;
                IsServiceRunning = false;
                if (_uptimeTimer != null)
                {
                    _uptimeTimer.IsEnabled = false;
                }
                ClearAllData();
            });

            // 关闭并释放命名管道客户端
            if (_namedPipeClient != null)
            {
                try
                {
                    _namedPipeClient.Close();
                    _namedPipeClient.Dispose();
                }
                catch { }
                finally
                {
                    _namedPipeClient = null;
                }
            }
        }

        /// <summary>
        /// 清空所有数据
        /// </summary>
        private void ClearAllData()
        {            
            ServiceStartTime = null;
            UptimeDisplay = "00:00:00";
            TotalQueries = 0;
            CacheHits = 0;
        }

        /// <summary>
        /// 运行时间计时器的Tick事件处理程序
        /// </summary>
        /// <param name="sender">事件发送者</param>
        /// <param name="e">事件参数</param>
        private void UptimeTimer_Tick(object? sender, EventArgs e)
        {            
            UpdateUptimeDisplay();
        }

        /// <summary>
        /// 更新运行时间显示
        /// </summary>
        private void UpdateUptimeDisplay()
        {            
            if (ServiceStartTime.HasValue)
            {
                TimeSpan uptime = DateTime.Now - ServiceStartTime.Value;
                UptimeDisplay = $"{uptime.Hours:D2}:{uptime.Minutes:D2}:{uptime.Seconds:D2}";
            }
            else
            {
                UptimeDisplay = "00:00:00";
            }
        }

        #endregion

        #region 窗口事件

        /// <summary>
        /// 窗口关闭事件
        /// </summary>
        protected override void OnClosed(EventArgs e)
        {            
            // 取消连接监控任务
            if (_cts != null)
            {
                _cts.Cancel();
                _cts.Dispose();
            }

            // 停止定时器
            if (_uptimeTimer != null)
            {
                _uptimeTimer.Stop();
                _uptimeTimer = null;
            }

            // 关闭命名管道客户端
            if (_namedPipeClient != null)
            {
                try
                {                    
                    _namedPipeClient.Close();
                    _namedPipeClient.Dispose();
                }
                catch { }
            }

            base.OnClosed(e);
        }

        #endregion

        #region 按钮事件处理

        /// <summary>
        /// 服务控制按钮点击事件
        /// </summary>
        private async void ServiceToggleButton_Click(object sender, RoutedEventArgs e)
        {            
            try
            {
                if (IsServiceRunning)
                {
                    await StopServiceAsync();
                }
                else
                {
                    await StartServiceAsync();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"操作服务失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// 启动服务
        /// </summary>
        private async Task StartServiceAsync()
        {            
            // 尝试启动服务进程
            await StartLdnsProcessAsync();
        }

        /// <summary>
        /// 启动LDNS进程
        /// </summary>
        private async Task StartLdnsProcessAsync()
        {            
            try
            {
                bool startedSuccessfully = false;
                string[] possiblePaths = new string[]
                {
                    "LDNS.exe", // 当前目录
                    "..\\LDNS.exe", // 上一级目录
                    "..\\..\\net8.0\\win-x64\\LDNS.exe", // 输出目录
                };

                // 尝试从可能的路径启动LDNS.exe
                foreach (string path in possiblePaths)
                {
                    if (File.Exists(path))
                    {
                        try
                        {
                            ProcessStartInfo processStartInfo = new ProcessStartInfo
                            {
                                FileName = Path.GetFullPath(path),
                                Arguments = "-s",
                                UseShellExecute = true,
                                CreateNoWindow = true,
                                WindowStyle = ProcessWindowStyle.Hidden, // 隐藏窗口
                                Verb = "runas" // 以管理员身份运行
                            };

                            Process? process = Process.Start(processStartInfo);
                            if (process != null)
                            {
                                _logger.Debug($"成功从路径启动LDNS进程: {path}");
                                startedSuccessfully = true;
                                await Task.Delay(2000); // 等待服务启动
                                break;
                            }
                        }
                        catch (Exception ex)
                        {
                            _logger.Debug($"尝试从路径启动失败 {path}: {ex.Message}");
                            // 继续尝试下一个路径
                        }
                    }
                }

                // 如果EXE启动失败，尝试使用dotnet运行DLL
                if (!startedSuccessfully)
                {
                    string[] possibleDllPaths = new string[]
                    {
                        "LDNS.dll", // 当前目录
                        "..\\LDNS.dll", // 上一级目录
                        "..\\..\\net8.0\\win-x64\\LDNS.dll", // 输出目录
                    };

                    foreach (string dllPath in possibleDllPaths)
                    {
                        if (File.Exists(dllPath))
                        {
                            try
                            {
                                ProcessStartInfo processStartInfo = new ProcessStartInfo
                                {
                                    FileName = "dotnet",
                                    Arguments = $"{Path.GetFullPath(dllPath)} -s",
                                    UseShellExecute = true,
                                    CreateNoWindow = true,
                                    Verb = "runas" // 以管理员身份运行
                                };

                                Process? process = Process.Start(processStartInfo);
                                if (process != null)
                                {
                                    _logger.Debug($"成功使用dotnet启动LDNS DLL: {dllPath}");
                                    startedSuccessfully = true;
                                    await Task.Delay(2000); // 等待服务启动
                                    break;
                                }
                            }
                            catch (Exception ex)
                            {
                                _logger.Debug($"尝试使用dotnet启动失败 {dllPath}: {ex.Message}");
                                // 继续尝试下一个路径
                            }
                        }
                    }
                }

                // 如果启动成功，尝试连接
                if (startedSuccessfully)
                {
                    // 重启连接尝试
                    ResetConnectionState();
                    ConnectToIpcService();
                }
                else
                {
                    throw new Exception("无法找到并启动LDNS服务进程。请检查应用程序是否正确构建。");
                }
            }
            catch (Exception ex)
            {
                _logger.Debug($"启动LDNS进程失败: {ex.Message}");
                throw;
            }
        }

        /// <summary>
        /// 停止服务
        /// </summary>
        private async Task StopServiceAsync()
        {            
            try
            {
                // 发送停止命令
                if (_namedPipeClient != null && _namedPipeClient.IsConnected)
                {
                    string stopCommand = "STOP\n";
                    byte[] commandBytes = Encoding.UTF8.GetBytes(stopCommand);
                    await _namedPipeClient.WriteAsync(commandBytes, 0, commandBytes.Length);
                    await _namedPipeClient.FlushAsync();
                }

                // 尝试通过进程名终止
                foreach (Process process in Process.GetProcessesByName("LDNS"))
                {
                    try
                    {                        
                        process.Kill();
                        await Task.Delay(1000);
                    }
                    catch { }
                }

                // 重置连接状态
                ResetConnectionState();
            }
            catch (Exception ex)
            {
                _logger.Debug($"停止服务失败: {ex.Message}");
                throw;
            }
        }

        #endregion
    }
}